#pragma once
#include <stdio.h>
#include "com_define.h"

class NonCopyable 
{
private:
	NonCopyable(const NonCopyable &);
	const NonCopyable & operator=(const NonCopyable &);

protected:
	NonCopyable() {}
	virtual ~NonCopyable() {}
};

template<typename TYPE, typename REFTYPE = TYPE>
class AutoSingleton : private NonCopyable 
{
public:
	static REFTYPE & Instance() 
	{
		static TYPE s_single_obj;
		return  s_single_obj;
	}

protected:
	AutoSingleton() {}
	virtual ~AutoSingleton() {}
};

template<typename TYPE, typename PTYPE = TYPE>
class ManualSingleton : private NonCopyable 
{
public:
	static PTYPE* Instance()
	{
		MMO_ASSERT(!is_destroyed_);
		if (is_destroyed_)
			return  NULL;

		if (!object_ptr_) 
		{
			if (!object_ptr_)
				object_ptr_ = new TYPE();
		}
		return object_ptr_;
	}

	static bool IsBeing()
	{
		bool result = false;
		if (object_ptr_)
		{
			result = true;
		}
		return result;
	}

	static PTYPE* GetInstance() 
	{
		MMO_ASSERT(object_ptr_);
		return object_ptr_;
	}

	static void Destroy() 
	{
		if (object_ptr_) 
		{
			delete (object_ptr_);
			object_ptr_   = NULL;
			is_destroyed_ = true;
		}
	}

protected:
	static bool   is_destroyed_;
	static PTYPE*  object_ptr_;

protected:
	ManualSingleton() {}
	virtual ~ManualSingleton() {}
};

template<typename TYPE, typename PTYPE> PTYPE *
ManualSingleton<TYPE, PTYPE>::object_ptr_   = NULL;
template<typename TYPE, typename PTYPE> bool
ManualSingleton<TYPE, PTYPE>::is_destroyed_ = false;
